package main

import (
	"bufio"
	"database/sql"
	"encoding/binary"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/websocket"
	"log"
	"net"
	"os"
	"time"
)

// TowerCraneData1 设备实时数据上传
type TowerCraneData1 struct {
	ManufacturerID  uint32 // 厂家编号
	ProtocolVersion uint32 // 协议版本
	DeviceType      uint32 // 设备类型
	Timestamp       time.Time
}

// TowerCraneData3 设备实时数据上传
type TowerCraneData3 struct {
	Timestamp         time.Time
	Height            float32
	Radius            float32
	Rotation          float32
	Weight            float32
	SafeWeight        float32
	SafeWeightPercent uint8
	Moment            float32
	MomentLoadPercent uint8
	WindSpeed         float32
	TiltX             float32
	TiltY             float32
	DeviceStatus      float32
	Depth             float32
	Checksum          uint8
}

// TowerCraneData2 设备属性信息上传
type TowerCraneData2 struct {
	SIMCardNumber      string  // SIM卡号，20字节 ASCII
	GroupTowerID       uint16  // 群塔ID，2字节，0-65535
	TowerInGroupID     uint16  // 塔机在群ID，2字节，0-65535
	RopeMultiplier     uint8   // 吊绳倍率，1字节
	TowerCoordinatesX  float32 // 塔机X坐标和Y坐标，各4字节，精度两位小数
	TowerCoordinatesY  float32 // 塔机X坐标和Y坐标，各4字节，精度两位小数
	ArmLength1         float32 // 臂长度，4字节，精度两位小数
	ArmLength2         float32 // 臂长度，4字节，精度两位小数
	TowerHeight        float32 // 塔帽长度，4字节，精度两位小数
	TowerHeightAbove   float32 // 塔身高度，4字节，精度两位小数
	Longtitude         float32 // 塔机安装经度和纬度，各4字节，精度六位小数
	Latitude           float32 // 塔机安装经度和纬度，各4字节，精度六位小数
	TurnMaxLeft        float32 // 左转最大幅度，精度两位小数
	TurnMaxRight       float32 // 右转最大幅度，精度两位小数
	TrolleyFrontLimit  float32 // 小车前极限，精度两位小数
	TrolleyBackLimit   float32 // 小车后极限，精度两位小数
	HoistingHeight     float32 // 起升高度，精度两位小数
	MaxLiftingCapacity float32 // 最大起重量
	Maxweight          float32
	TorqueWarningPct   uint8 // 力矩限预警百分比，0-255
	AlertPct           uint8 // 报警百分比，0-255
	ViolationPct       uint8 // 违章百分比，0-255

}
type TowerCraneData4 struct {
	Timestamp           time.Time
	StartTime           time.Time
	EndTime             time.Time
	MaxTload            float32
	LoadPercentage      uint8   // 百分比，精度到小数点后两位
	MaxTorque           float32 // 力矩，精度同上
	TorquePercentage    uint8   // 载重百分比，精度到小数点后两位
	Sangle              float32 // 转角，精度同上
	Eangle              float32 // 转角，精度同上
	SswingAngle         float32 // 幅度，精度同上
	EswingAngle         float32 // 幅度，精度同上
	MaxSwingAngle       float32 // 最大幅度
	MinSwingAngle       float32 // 最小幅度
	Startheight         float32
	Endheight           float32
	MaxLiftHeight       float32 // 最大起升高度
	MinLiftHeight       float32 // 最大起升高度
	MaxWorkingWindSpeed float32 // 最大工作风速
	MaxTiltAngleX       float32 // 最大倾角 X 轴
	MaxTiltAngleY       float32 // 最大倾角 Y 轴
	DeviceStatus        uint32  // 设备状态

}
type TowerCraneData5 struct {
	Timestamp    time.Time
	Driver_state uint8
	Driver_id    string
}

// 数据库配置
const (
	DBUser     = "root"           // 数据库用户名
	DBPassword = "770525"         // 数据库密码
	DBName     = "tower_crane_db" // 数据库名
)

var dataChannel = make(chan []byte)

func handleConnection(conn net.Conn, db *sql.DB) {
	defer conn.Close()
	fmt.Printf("New connection from %s\n", conn.RemoteAddr().String())
	reader := bufio.NewReader(conn)
	var data []byte // 用于存储当前正在处理的数据

	for {
		buffer := make([]byte, 2048) // 定义一个足够大的缓冲区
		n, err := reader.Read(buffer)
		if err != nil {
			fmt.Printf("Error reading from connection: %v\n", err)
			break
		}

		data = append(data, buffer[:n]...)

		for len(data) >= 10 { // 假设帧头和帧尾至少占用 10 个字节
			expectedLength := uint8(data[2])
			frameLength := uint8(len(data))

			if frameLength < expectedLength {
				// 数据不完整，等待更多数据
				break
			}

			packetData := data[:expectedLength]
			data = data[expectedLength:] // 移除已处理的包数据

			if binary.BigEndian.Uint16(packetData[:2]) != 0xA55A || binary.BigEndian.Uint32(packetData[(packetData[2])-4:]) != 0xCC33C33C {
				fmt.Println("Invalid frame header or tail")
				continue
			}

			frameType := uint8(packetData[5])
			// 处理读取到的数据
			switch frameType {
			case 0x00: // 设备注册上传
				handleDeviceRegistration(packetData, db, conn)
				dataChannel <- packetData
			case 0x02: // 设备属性信息上传
				handleDeviceAttributeUpload(packetData, db, conn)
				dataChannel <- packetData
			case 0x04: // 设备心跳包上传
				handleHeartbeat(packetData, conn)
				dataChannel <- packetData
			case 0x06: // 设备实时数据上传
				handleRealTimeDataUpload(packetData, db, conn)
				dataChannel <- packetData
			case 0x08: // 吊装数据上传
				handleHoistingDataUpload(packetData, db, conn)
				dataChannel <- packetData
			case 0x0A: // 驾驶员信息上传
				handleDriverInfoUpload(packetData, db, conn)
				dataChannel <- packetData
			default:
				fmt.Println("Unknown frame type in TCP")
				return
			}
		}
	}
}

func sendToWebSocket(conn *websocket.Conn) {
	for data := range dataChannel {
		err := conn.WriteMessage(websocket.BinaryMessage, data)
		if err != nil {
			log.Println("Error sending data via WebSocket:", err)
			return
		}
	}
}

func main() {
	const host = "0.0.0.0"
	const port = "8088"

	address := fmt.Sprintf("%s:%s", host, port)
	listener, err := net.Listen("tcp", address)
	if err != nil {
		fmt.Printf("Error listening on %s: %v\n", address, err)
		os.Exit(1)
	}
	defer listener.Close()
	fmt.Printf("Listening on %s...\n", address)

	// 连接数据库
	db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/%s?parseTime=true", DBUser, DBPassword, DBName))
	if err != nil {
		fmt.Printf("Error connecting to the database: %v\n", err)
		os.Exit(1)
	}
	defer db.Close()

	if err := db.Ping(); err != nil {
		fmt.Printf("Error pinging the database: %v\n", err)
		os.Exit(1)
	}

	// 创建 WebSocket 连接
	wsURL := "ws://127.0.0.1:8085/ws"
	conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
	if err != nil {
		log.Fatal("Error connecting to WebSocket server:", err)
	}
	defer conn.Close()

	// 启动 WebSocket 发送协程
	go sendToWebSocket(conn)

	for {
		conn, err := listener.Accept()

		if err != nil {
			fmt.Printf("Error accepting connection: %v\n", err)
			continue
		}
		go handleConnection(conn, db)
	}
}

// calculateChecksum 计算校验和
func calculateChecksum(data []byte) uint8 {
	sum := uint32(0) // 使用 uint32 避免溢出
	for _, b := range data {
		sum += uint32(b) // 将 byte 转换为 uint32 进行累加
	}
	return uint8(sum % 256) // 模 256 确保结果在 uint8 的范围内
}

// insertData1 设备属性信息上传
func insertData1(db *sql.DB, data TowerCraneData1) {
	stmt := "INSERT INTO crane_data1 (manufacturerID,protocolVersion,deviceType,timestamp) VALUES (?,?,?,?)"
	_, err := db.Exec(stmt, data.ManufacturerID, data.ProtocolVersion, data.DeviceType, data.Timestamp)
	if err != nil {
		fmt.Printf("Error inserting data into the database: %v\n", err)
		return
	}
	fmt.Println("Data1 inserted successfully")
}

// insertData2 设备属性信息上传
func insertData2(db *sql.DB, data TowerCraneData2) {
	stmt := "INSERT INTO crane_data2 (sIMCardNumber,groupTowerID, towerInGroupID,  ropeMultiplier,towerCoordinatesX, towerCoordinatesY,armLength1,  armLength2,  towerHeight,  towerHeightAbove, longtitude,  latitude,turnMaxLeft,  turnMaxRight,trolleyFrontLimit,trolleyBackLimit,   hoistingHeight, maxLiftingCapacity, maxweight,torqueWarningPct, alertPct, violationPct) VALUES ( ?,?,?,?,?,?,?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
	_, err := db.Exec(stmt, data.SIMCardNumber, data.GroupTowerID, data.TowerInGroupID, data.RopeMultiplier, data.TowerCoordinatesX, data.TowerCoordinatesY, data.ArmLength1, data.ArmLength2, data.TowerHeight, data.TowerHeightAbove, data.Longtitude, data.Latitude, data.TurnMaxLeft, data.TurnMaxRight, data.TrolleyFrontLimit, data.TrolleyBackLimit, data.HoistingHeight, data.MaxLiftingCapacity, data.Maxweight, data.TorqueWarningPct, data.AlertPct, data.ViolationPct)
	if err != nil {
		fmt.Printf("Error inserting data into the database: %v\n", err)
		return
	}

	fmt.Println("Data2 inserted successfully")
}

// insertData2 设备实时数据上传
func insertData3(db *sql.DB, data TowerCraneData3) {
	stmt := "INSERT INTO crane_data3 ( timestamp,height, radius, rotation, weight, safe_weight, safe_weight_percent, moment, moment_load_percent, wind_speed, tilt_x, tilt_y, device_status, depth, checksum) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
	_, err := db.Exec(stmt, data.Timestamp, data.Height, data.Radius, data.Rotation, data.Weight, data.SafeWeight, data.SafeWeightPercent, data.Moment, data.MomentLoadPercent, data.WindSpeed, data.TiltX, data.TiltY, data.DeviceStatus, data.Depth, data.Checksum)
	if err != nil {
		fmt.Printf("Error inserting data into the database: %v\n", err)
		return
	}

	fmt.Println("Data3 inserted successfully")
}

// insertData2 设备实时数据上传
func insertData4(db *sql.DB, data TowerCraneData4) {
	// 构造 SQL 插入语句，确保列名与结构体字段匹配
	stmt := `INSERT INTO crane_data4 (timestamp,startTime,endTime, maxTload,loadPercentage,maxTorque,torquePercentage,sangle,eangle,sswingAngle,eswingAngle,maxSwingAngle,minSwingAngle,startheight,endheight, maxLiftHeight,minLiftHeight,maxWorkingWindSpeed,maxTiltAngleX,maxTiltAngleY,deviceStatus) VALUES (?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
	_, err := db.Exec(stmt, data.Timestamp, data.StartTime, data.EndTime, data.MaxTload, data.LoadPercentage, data.MaxTorque, data.TorquePercentage, data.Sangle, data.Eangle, data.SswingAngle, data.EswingAngle, data.MaxSwingAngle, data.MinSwingAngle, data.Startheight, data.Endheight, data.MaxLiftHeight, data.MinLiftHeight, data.MaxWorkingWindSpeed, data.MaxTiltAngleX, data.MaxTiltAngleY, data.DeviceStatus)
	if err != nil {
		fmt.Printf("Error inserting data into the database: %v\n", err)
		return
	}
	fmt.Println("Data4 inserted successfully")
}
func insertData5(db *sql.DB, data TowerCraneData5) {
	stmt := "INSERT INTO crane_data5 (timestamp,driver_state,driver_id) VALUES (?,?,?)"
	_, err := db.Exec(stmt, data.Timestamp, data.Driver_state, data.Driver_id)
	if err != nil {
		fmt.Printf("Error inserting data into the database: %v\n", err)
		return
	}
	fmt.Println("Data5 inserted successfully")
}
func bytesToTime(bytes []byte) time.Time {
	timestamp := int64(binary.BigEndian.Uint32(bytes))
	return time.Unix(timestamp, 0)
}

func handleDeviceRegistration(data []byte, db *sql.DB, conn net.Conn) {
	manufacturerID := uint32(data[3])
	protocolVersion := uint32(data[4])
	deviceType := binary.BigEndian.Uint32(data[6:10])
	timestamp := bytesToTime(data[6:10])
	checksum := uint8(data[14])
	// 验证校验和
	expectedChecksum := calculateChecksum(data[:(data[2])-5])
	if checksum != expectedChecksum {
		fmt.Println("Checksum error")
		return
	}
	responseFrame := []byte{data[0], data[1], data[2], data[3], data[4], 0x01, data[6], data[7], data[8], data[9], data[14], data[15], data[16], data[17], data[18]} // 假设的响应帧格式
	_, err := conn.Write(responseFrame)
	time.Sleep(1 * time.Second)
	if err != nil {
		fmt.Printf("Error sending acknowledgment frame: %v\n", err)
		return
	}
	craneData1 := TowerCraneData1{
		ManufacturerID:  manufacturerID,
		ProtocolVersion: protocolVersion,
		DeviceType:      deviceType,
		Timestamp:       timestamp,
	}
	fmt.Printf("Processed data: %+v\n", craneData1)
	// 插入数据到数据库
	insertData1(db, craneData1)
}

func handleDeviceAttributeUpload(data []byte, db *sql.DB, conn net.Conn) {
	sIMCardNumber := string(data[10:30])
	groupTowerID := binary.BigEndian.Uint16(data[30:32])
	towerInGroupID := binary.BigEndian.Uint16(data[32:34])
	ropeMultiplier := uint8(data[34])
	towerCoordinatesX := float32(binary.BigEndian.Uint32(data[35:39])) / 100
	towerCoordinatesY := float32(binary.BigEndian.Uint32(data[39:43])) / 100
	armLength1 := float32(binary.BigEndian.Uint32(data[43:47])) / 100
	armLength2 := float32(binary.BigEndian.Uint32(data[47:51])) / 100
	towerHeight := float32(binary.BigEndian.Uint32(data[51:55])) / 100
	towerHeightAbove := float32(binary.BigEndian.Uint32(data[55:59])) / 100
	longtitude := float32(binary.BigEndian.Uint32(data[59:63])) / 1000000
	latitude := float32(binary.BigEndian.Uint32(data[63:67])) / 1000000
	turnMaxLeft := float32(binary.BigEndian.Uint32(data[67:71])) / 100
	turnMaxRight := float32(binary.BigEndian.Uint32(data[71:75])) / 100
	trolleyFrontLimit := float32(binary.BigEndian.Uint32(data[75:79])) / 100
	trolleyBackLimit := float32(binary.BigEndian.Uint32(data[79:83])) / 100
	hoistingHeight := float32(binary.BigEndian.Uint32(data[83:87])) / 100
	maxLiftingCapacity := float32(binary.BigEndian.Uint32(data[87:91])) / 100
	maxweight := float32(binary.BigEndian.Uint32(data[91:95])) / 100
	torqueWarningPct := uint8(data[95])
	alertPct := uint8(data[96])
	violationPct := uint8(data[97])
	checksum := uint8(data[98])
	// 验证校验和
	expectedChecksum := calculateChecksum(data[:(data[2])-5])
	if checksum != expectedChecksum {
		fmt.Println("Checksum error")

	}
	responseFrame := []byte{data[0], data[1], data[2], data[3], data[4], 0x03, data[6], data[7], data[8], data[9], data[98], data[99], data[100], data[101], data[102]} // 假设的响应帧格式
	_, err := conn.Write(responseFrame)
	time.Sleep(1 * time.Second)
	if err != nil {
		fmt.Printf("Error sending acknowledgment frame: %v\n", err)
		return
	}
	// 将解析的数据转换为TowerCraneData结构体
	craneData2 := TowerCraneData2{
		SIMCardNumber:      sIMCardNumber,
		GroupTowerID:       groupTowerID,
		TowerInGroupID:     towerInGroupID,
		RopeMultiplier:     ropeMultiplier,
		TowerCoordinatesX:  towerCoordinatesX,
		TowerCoordinatesY:  towerCoordinatesY,
		ArmLength1:         armLength1,
		ArmLength2:         armLength2,
		TowerHeight:        towerHeight,
		TowerHeightAbove:   towerHeightAbove,
		Longtitude:         longtitude,
		Latitude:           latitude,
		TurnMaxLeft:        turnMaxLeft,
		TurnMaxRight:       turnMaxRight,
		TrolleyFrontLimit:  trolleyFrontLimit,
		TrolleyBackLimit:   trolleyBackLimit,
		HoistingHeight:     hoistingHeight,
		MaxLiftingCapacity: maxLiftingCapacity,
		Maxweight:          maxweight,
		TorqueWarningPct:   torqueWarningPct,
		AlertPct:           alertPct,
		ViolationPct:       violationPct,
	}
	fmt.Printf("Processed data: %+v\n", craneData2)
	// 插入数据到数据库
	insertData2(db, craneData2)
}

func handleRealTimeDataUpload(data []byte, db *sql.DB, conn net.Conn) {
	timestamp := bytesToTime(data[10:14])
	height := float32(binary.BigEndian.Uint32(data[14:18])) / 100
	radius := float32(binary.BigEndian.Uint32(data[18:22])) / 100
	rotation := float32(binary.BigEndian.Uint32(data[22:26])) / 100
	weight := float32(binary.BigEndian.Uint32(data[26:30])) / 100
	safeWeight := float32(binary.BigEndian.Uint32(data[30:34])) / 100
	safeWeightPercent := uint8(data[34])
	moment := float32(binary.BigEndian.Uint32(data[35:39])) / 100
	momentLoadPercent := uint8(data[39])
	windSpeed := float32(binary.BigEndian.Uint32(data[40:44])) / 100
	tiltX := float32(binary.BigEndian.Uint32(data[44:48])) / 100
	tiltY := float32(binary.BigEndian.Uint32(data[48:52])) / 100
	deviceStatus := float32(binary.BigEndian.Uint32(data[52:56])) / 100
	depth := float32(binary.BigEndian.Uint32(data[56:60])) / 100
	checksum := uint8(data[60])
	// 验证校验和
	expectedChecksum := calculateChecksum(data[:(data[2])-5])
	if checksum != expectedChecksum {
		fmt.Println("Checksum error")
		return
	}
	responseFrame := []byte{data[0], data[1], data[2], data[3], data[4], 0x07, data[6], data[7], data[8], data[9], data[60], data[61], data[62], data[62], data[63]} // 假设的响应帧格式
	_, err := conn.Write(responseFrame)
	time.Sleep(1 * time.Second)
	if err != nil {
		fmt.Printf("Error sending acknowledgment frame: %v\n", err)
		return
	}
	// 将解析的数据转换为TowerCraneData结构体
	craneData3 := TowerCraneData3{
		Timestamp:         timestamp,
		Height:            height,
		Radius:            radius,
		Rotation:          rotation,
		Weight:            weight,
		SafeWeight:        safeWeight,
		SafeWeightPercent: safeWeightPercent,
		Moment:            moment,
		MomentLoadPercent: momentLoadPercent,
		WindSpeed:         windSpeed,
		TiltX:             tiltX,
		TiltY:             tiltY,
		DeviceStatus:      deviceStatus,
		Depth:             depth,
		Checksum:          checksum,
	}
	fmt.Printf("Processed data: %+v\n", craneData3)
	// 插入数据到数据库
	insertData3(db, craneData3)
}

func handleHoistingDataUpload(data []byte, db *sql.DB, conn net.Conn) {
	timestamp := bytesToTime(data[10:14])
	startTime := bytesToTime(data[14:18])
	endTime := bytesToTime(data[18:22])
	maxTload := float32(binary.BigEndian.Uint32(data[22:26])) / 100
	loadPercentage := uint8(data[26])
	maxTorque := float32(binary.BigEndian.Uint32(data[27:31])) / 100
	torquePercentage := uint8(data[31])
	sangle := float32(binary.BigEndian.Uint32(data[32:36])) / 100
	eangle := float32(binary.BigEndian.Uint32(data[36:40])) / 100
	sswingAngle := float32(binary.BigEndian.Uint32(data[40:44])) / 100
	eswingAngle := float32(binary.BigEndian.Uint32(data[44:48])) / 100
	maxSwingAngle := float32(binary.BigEndian.Uint32(data[48:52])) / 100
	minSwingAngle := float32(binary.BigEndian.Uint32(data[52:56])) / 100
	startheight := float32(binary.BigEndian.Uint32(data[56:60])) / 100
	endheight := float32(binary.BigEndian.Uint32(data[60:64])) / 100
	maxLiftHeight := float32(binary.BigEndian.Uint32(data[64:68])) / 100
	minLiftHeight := float32(binary.BigEndian.Uint32(data[68:72])) / 100
	maxWorkingWindSpeed := float32(binary.BigEndian.Uint32(data[72:76])) / 100
	maxTiltAngleX := float32(binary.BigEndian.Uint32(data[76:80])) / 100
	maxTiltAngleY := float32(binary.BigEndian.Uint32(data[80:84])) / 100
	deviceStatus := binary.BigEndian.Uint32(data[84:88])
	checksum := uint8(data[88])

	// 验证校验和
	expectedChecksum := calculateChecksum(data[:(data[2])-5])
	if checksum != expectedChecksum {
		fmt.Println("Checksum error")

	}
	responseFrame := []byte{data[0], data[1], data[2], data[3], data[4], 0x09, data[6], data[7], data[8], data[9], data[88], data[89], data[90], data[91], data[92]} // 假设的响应帧格式
	_, err := conn.Write(responseFrame)
	time.Sleep(1 * time.Second)
	if err != nil {
		fmt.Printf("Error sending acknowledgment frame: %v\n", err)
		return
	}
	// 将解析的数据转换为TowerCraneData结构体
	craneData4 := TowerCraneData4{

		Timestamp:           timestamp,
		StartTime:           startTime,
		EndTime:             endTime,
		MaxTload:            maxTload,
		LoadPercentage:      loadPercentage,
		MaxTorque:           maxTorque,
		TorquePercentage:    torquePercentage,
		Sangle:              sangle,
		Eangle:              eangle,
		SswingAngle:         sswingAngle,
		EswingAngle:         eswingAngle,
		MaxSwingAngle:       maxSwingAngle,
		MinSwingAngle:       minSwingAngle,
		Startheight:         startheight,
		Endheight:           endheight,
		MaxLiftHeight:       maxLiftHeight,
		MinLiftHeight:       minLiftHeight,
		MaxWorkingWindSpeed: maxWorkingWindSpeed,
		MaxTiltAngleX:       maxTiltAngleX,
		MaxTiltAngleY:       maxTiltAngleY,
		DeviceStatus:        deviceStatus,
	}
	fmt.Printf("Processed data: %+v\n", craneData4)
	// 插入数据到数据库
	insertData4(db, craneData4)
}

func handleDriverInfoUpload(data []byte, db *sql.DB, conn net.Conn) {
	timestamp := bytesToTime(data[10:14])
	driver_state := uint8(data[14])
	driver_id := string(data[15:33])
	checksum := uint8(data[35])
	// 验证校验和
	expectedChecksum := calculateChecksum(data[:(data[2])-5])
	if checksum != expectedChecksum {
		fmt.Println("Checksum error")
		return
	}
	responseFrame := []byte{data[0], data[1], data[2], data[3], data[4], 0x0B, data[6], data[7], data[8], data[9], data[35], data[36], data[37], data[38], data[39]} // 假设的响应帧格式
	_, err := conn.Write(responseFrame)
	time.Sleep(1 * time.Second)
	if err != nil {
		fmt.Printf("Error sending acknowledgment frame: %v\n", err)
		return
	}
	craneData5 := TowerCraneData5{
		Timestamp:    timestamp,
		Driver_state: driver_state,
		Driver_id:    driver_id,
	}
	fmt.Printf("Processed data: %+v\n", craneData5)
	// 插入数据到数据库
	insertData5(db, craneData5)
}
func handleHeartbeat(data []byte, conn net.Conn) {
	// 模拟服务器应答设备心跳包
	responseFrame := []byte{data[0], data[1], data[2], data[3], data[4], 0x05, data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14]} // 假设的响应帧格式
	_, err := conn.Write(responseFrame)
	if err != nil {
		fmt.Println("Error writing response in heartbeat:", err.Error())
		return
	}
}
